package framework.captcha;

import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.RandomStringUtils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;

/**
 * 验证码
 */
public class CaptchaGenerator {

    @Getter
    private int width = 150;
    @Getter
    private int height = 48;
    @Getter
    @Setter
    private int length = 4;
    @Getter
    @Setter
    private int fontWidth = 27;
    @Getter
    @Setter
    private int fontHeight = 42;
    @Getter
    @Setter
    private int codeYBase = 40;
    @Getter
    @Setter
    private boolean isNoise = true;
    @Getter
    private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', /*'I',*/ 'J', 'K', /*'L',*/ 'M', 'N', /*'O', */'P', 'Q', 'R',
            'S', 'T', 'U', /*'V',*/ 'W', 'X', 'Y', 'Z', /*'0',*/ '1', '2', '3', '4', '5', '6', '7', '8', '9'};

    public CaptchaGenerator() {
    }

    public CaptchaGenerator(int width, int height) {
        this.width = width;
        this.height = height;
    }

    /**
     * 码生成
     *
     * @return
     */
    public CaptchaInfo generate() {
        String code = this.generateCode();
        BufferedImage image = this.generateImage(code);
        return new CaptchaInfo(code, image);
    }

    /**
     * 码生成
     *
     * @return
     */
    protected String generateCode() {
        String code = RandomStringUtils.random(this.length, codeSequence);
        return code;
    }

    /**
     * 字体名称
     *
     * @return
     */
    protected String getFontName() {
        return "Sans-serif";
    }

    /**
     * 噪声生成
     *
     * @param gd
     */
    protected void generateNoise(Graphics gd) {
        Random random = new Random();
        int red = 0, green = 0, blue = 0;
        for (int i = 0; i < 100; i++) {
            red = random.nextInt(250);
            green = random.nextInt(250);
            blue = random.nextInt(250);
            gd.setColor(new Color(red, green, blue));
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            gd.drawLine(x, y, x + 10, y + 10);
        }
    }

    /**
     * 码生成
     *
     * @return
     */
    protected BufferedImage generateImage(String code) {
        BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics gd = buffImg.getGraphics();
        Random random = new Random();
        gd.setColor(Color.WHITE);
        gd.fillRect(0, 0, width, height);
        Font font = new Font(this.getFontName(), Font.PLAIN, fontHeight);
        gd.setFont(font);
        int red = 0, green = 0, blue = 0;

        char[] codes = code.toCharArray();
        int preWidth = fontWidth - (int)(fontWidth * 0.75f);
        for (int i = 0; i < codes.length; i++) {
            red = random.nextInt(255);
            green = random.nextInt(255);
            blue = random.nextInt(255);
            gd.setColor(new Color(red, green, blue));
            gd.drawString(String.valueOf(codes[i]), (i + 1) * fontWidth - preWidth, codeYBase);
        }

        //
        //
        if (this.isNoise())
            this.generateNoise(gd);

        //
        return buffImg;
    }

    public static void main(String[] args) throws Exception {

        for (int i = 0; i < 10; i++) {
            File file = new File("/tmp/simpleCode" + i + ".jpg");
            try {
                try (FileOutputStream out = new FileOutputStream(file)) {
                    CaptchaInfo captchaInfo = new CaptchaGenerator().generate();
                    ImageIO.write(captchaInfo.getImage(), "jpeg", out);
                    System.out.println("SimpleCode: " + captchaInfo.getCode());
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}